﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Generator.Tools
{
    public partial class EncodeConvert : ToolsBase
    {

        private readonly string _testFileRoot = GlobalValues.CurrentPath + "\\WSTestFiles";

        public EncodeConvert()
        {
            InitializeComponent();
        }

        private void EncodeConvert_Load(object sender, EventArgs e)
        {
            encodingList1.Items.Add("default");
            #region encoding list
            encodingList1.Items.Add("IBM037");
            encodingList1.Items.Add("IBM437");
            encodingList1.Items.Add("IBM500");
            encodingList1.Items.Add("ASMO-708");
            encodingList1.Items.Add("DOS-720");
            encodingList1.Items.Add("ibm737");
            encodingList1.Items.Add("ibm775");
            encodingList1.Items.Add("ibm850");
            encodingList1.Items.Add("ibm852");
            encodingList1.Items.Add("IBM855");
            encodingList1.Items.Add("ibm857");
            encodingList1.Items.Add("IBM00858");
            encodingList1.Items.Add("IBM860");
            encodingList1.Items.Add("ibm861");
            encodingList1.Items.Add("DOS-862");
            encodingList1.Items.Add("IBM863");
            encodingList1.Items.Add("IBM864");
            encodingList1.Items.Add("IBM865");
            encodingList1.Items.Add("cp866");
            encodingList1.Items.Add("ibm869");
            encodingList1.Items.Add("IBM870");
            encodingList1.Items.Add("windows-874");
            encodingList1.Items.Add("cp875");
            encodingList1.Items.Add("shift_jis");
            encodingList1.Items.Add("gb2312");
            encodingList1.Items.Add("ks_c_5601-1987");
            encodingList1.Items.Add("big5");
            encodingList1.Items.Add("IBM1026");
            encodingList1.Items.Add("IBM01047");
            encodingList1.Items.Add("IBM01140");
            encodingList1.Items.Add("IBM01141");
            encodingList1.Items.Add("IBM01142");
            encodingList1.Items.Add("IBM01143");
            encodingList1.Items.Add("IBM01144");
            encodingList1.Items.Add("IBM01145");
            encodingList1.Items.Add("IBM01146");
            encodingList1.Items.Add("IBM01147");
            encodingList1.Items.Add("IBM01148");
            encodingList1.Items.Add("IBM01149");
            encodingList1.Items.Add("utf-16");
            encodingList1.Items.Add("unicodeFFFE");
            encodingList1.Items.Add("windows-1250");
            encodingList1.Items.Add("windows-1251");
            encodingList1.Items.Add("Windows-1252");
            encodingList1.Items.Add("windows-1253");
            encodingList1.Items.Add("windows-1254");
            encodingList1.Items.Add("windows-1255");
            encodingList1.Items.Add("windows-1256");
            encodingList1.Items.Add("windows-1257");
            encodingList1.Items.Add("windows-1258");
            encodingList1.Items.Add("Johab");
            encodingList1.Items.Add("macintosh");
            encodingList1.Items.Add("x-mac-japanese");
            encodingList1.Items.Add("x-mac-chinesetrad");
            encodingList1.Items.Add("x-mac-korean");
            encodingList1.Items.Add("x-mac-arabic");
            encodingList1.Items.Add("x-mac-hebrew");
            encodingList1.Items.Add("x-mac-greek");
            encodingList1.Items.Add("x-mac-cyrillic");
            encodingList1.Items.Add("x-mac-chinesesimp");
            encodingList1.Items.Add("x-mac-romanian");
            encodingList1.Items.Add("x-mac-ukrainian");
            encodingList1.Items.Add("x-mac-thai");
            encodingList1.Items.Add("x-mac-ce");
            encodingList1.Items.Add("x-mac-icelandic");
            encodingList1.Items.Add("x-mac-turkish");
            encodingList1.Items.Add("x-mac-croatian");
            encodingList1.Items.Add("utf-32");
            encodingList1.Items.Add("utf-32BE");
            encodingList1.Items.Add("x-Chinese-CNS");
            encodingList1.Items.Add("x-cp20001");
            encodingList1.Items.Add("x-Chinese-Eten");
            encodingList1.Items.Add("x-cp20003");
            encodingList1.Items.Add("x-cp20004");
            encodingList1.Items.Add("x-cp20005");
            encodingList1.Items.Add("x-IA5");
            encodingList1.Items.Add("x-IA5-German");
            encodingList1.Items.Add("x-IA5-Swedish");
            encodingList1.Items.Add("x-IA5-Norwegian");
            encodingList1.Items.Add("us-ascii");
            encodingList1.Items.Add("x-cp20261");
            encodingList1.Items.Add("x-cp20269");
            encodingList1.Items.Add("IBM273");
            encodingList1.Items.Add("IBM277");
            encodingList1.Items.Add("IBM278");
            encodingList1.Items.Add("IBM280");
            encodingList1.Items.Add("IBM284");
            encodingList1.Items.Add("IBM285");
            encodingList1.Items.Add("IBM290");
            encodingList1.Items.Add("IBM297");
            encodingList1.Items.Add("IBM420");
            encodingList1.Items.Add("IBM423");
            encodingList1.Items.Add("IBM424");
            encodingList1.Items.Add("x-EBCDIC-KoreanExtended");
            encodingList1.Items.Add("IBM-Thai");
            encodingList1.Items.Add("koi8-r");
            encodingList1.Items.Add("IBM871");
            encodingList1.Items.Add("IBM880");
            encodingList1.Items.Add("IBM905");
            encodingList1.Items.Add("IBM00924");
            encodingList1.Items.Add("EUC-JP");
            encodingList1.Items.Add("x-cp20936");
            encodingList1.Items.Add("x-cp20949");
            encodingList1.Items.Add("cp1025");
            encodingList1.Items.Add("koi8-u");
            encodingList1.Items.Add("iso-8859-1");
            encodingList1.Items.Add("iso-8859-2");
            encodingList1.Items.Add("iso-8859-3");
            encodingList1.Items.Add("iso-8859-4");
            encodingList1.Items.Add("iso-8859-5");
            encodingList1.Items.Add("iso-8859-6");
            encodingList1.Items.Add("iso-8859-7");
            encodingList1.Items.Add("iso-8859-8");
            encodingList1.Items.Add("iso-8859-9");
            encodingList1.Items.Add("iso-8859-13");
            encodingList1.Items.Add("iso-8859-15");
            encodingList1.Items.Add("x-Europa");
            encodingList1.Items.Add("iso-8859-8-i");
            encodingList1.Items.Add("iso-2022-jp");
            encodingList1.Items.Add("csISO2022JP");
            encodingList1.Items.Add("iso-2022-jp");
            encodingList1.Items.Add("iso-2022-kr");
            encodingList1.Items.Add("x-cp50227");
            encodingList1.Items.Add("euc-jp");
            encodingList1.Items.Add("EUC-CN");
            encodingList1.Items.Add("euc-kr");
            encodingList1.Items.Add("hz-gb-2312");
            encodingList1.Items.Add("GB18030");
            encodingList1.Items.Add("x-iscii-de");
            encodingList1.Items.Add("x-iscii-be");
            encodingList1.Items.Add("x-iscii-ta");
            encodingList1.Items.Add("x-iscii-te");
            encodingList1.Items.Add("x-iscii-as");
            encodingList1.Items.Add("x-iscii-or");
            encodingList1.Items.Add("x-iscii-ka");
            encodingList1.Items.Add("x-iscii-ma");
            encodingList1.Items.Add("x-iscii-gu");
            encodingList1.Items.Add("x-iscii-pa");
            encodingList1.Items.Add("utf-7");
            encodingList1.Items.Add("utf-8");
            #endregion

            encodingList2.Items.Add(Encoding.UTF8);

            encodingList1.SelectedIndex = 0;
            encodingList2.SelectedIndex = 0;

            //treeView1.Nodes.Add("WSTestRoot", "WSTest");
            //LoadWsTestFiles();


            //treeView2.Nodes.Add("WSTestRoot", "WSTest");
            //LoadWsTestFiles();

        }

        //private void LoadWsTestFiles()
        //{
        //    if (!Directory.Exists(_testFileRoot))
        //    {
        //        Directory.CreateDirectory(_testFileRoot);
        //    }
        //    DirectoryInfo di = new DirectoryInfo(_testFileRoot);

        //    var treeNode = treeView1.TopNode;
        //    treeNode.Nodes.Clear();
        //    AddFilesToTrees(treeNode, di);
        //}

        private void AddDirectoryToTrees(DirectoryInfo direcory)
        {
            DirectoryInfo rootDi = new DirectoryInfo(folderBrowserDialog1.SelectedPath);

            string[] exts = txtExtension.Text.Split(new char[] { ',' });
            foreach (var ext in exts)
            {
                foreach (FileInfo fi in direcory.GetFiles(ext))
                {
                    addFileToListView(new FileRootDirectory { FileInfo = fi, RootDirectory = rootDi.Parent.FullName });
                }
            }

            foreach (DirectoryInfo di in direcory.GetDirectories())
            {
                AddDirectoryToTrees(di);
            }
        }

        private void btAddFile_Click(object sender, EventArgs e)
        {
            string filter = "", filterAll = "";
            string[] exts = txtExtension.Text.Split(new char[] { ',' });
            foreach (var ext in exts)
            {
                filter += string.Format("|{0}|{0}", ext);
                if (filterAll.Length > 0)
                    filterAll += ";";
                filterAll += ext;
            }

            filterAll = string.Format("{0}|{1}", txtExtension.Text, filterAll);

            openFileDialog1.Filter = filterAll + filter;
            var res = openFileDialog1.ShowDialog();
            if (res != DialogResult.OK)
            {
                return;
            }

            foreach (var fn in openFileDialog1.FileNames)
            {
                FileInfo fi = new FileInfo(fn);
                addFileToListView(new FileRootDirectory { FileInfo = fi, RootDirectory = "" });
            }

        }

        private void addFileToListView(FileRootDirectory fi)
        {
            var item = new ListViewItem(fi.FileInfo.Name);
            item.SubItems.Add(fi.FileInfo.Directory.FullName);
            fi.Encoding = CheckEncoding(fi.FileInfo);
            item.SubItems.Add(fi.Encoding.BodyName);
            item.Tag = fi;
            item.Checked = true;
            listView1.Items.Add(item);
        }

        private void btAddDirectory_Click(object sender, EventArgs e)
        {
            var res = folderBrowserDialog1.ShowDialog();
            if (res != DialogResult.OK)
            {
                return;
            }

            DirectoryInfo di = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
            AddDirectoryToTrees(di);
        }

        private void btTargetDirectory_Click(object sender, EventArgs e)
        {
            var res = folderBrowserDialog1.ShowDialog();
            if (res != DialogResult.OK)
            {
                return;
            }

            txtTargetDirectory.Text = folderBrowserDialog1.SelectedPath;
        }

        private void btRemove_Click(object sender, EventArgs e)
        {
            List<ListViewItem> items = new List<ListViewItem>();
            foreach (ListViewItem item in listView1.Items)
            {
                if (item.Checked)
                {
                    items.Add(item);
                }
            }

            foreach (var item in items)
            {
                listView1.Items.Remove(item);
            }
        }


        private void btClear_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();

        }

        private void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
        {

        }

        private void btSelectAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in listView1.Items)
            {
                item.Checked = true;
            }
        }

        private void btSelectNone_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in listView1.Items)
            {
                item.Checked = false;
            }
        }

        private void convertToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (!Directory.Exists(txtTargetDirectory.Text))
            {
                Directory.CreateDirectory(txtTargetDirectory.Text);
            }

            while (true)
            {
                if (txtTargetDirectory.Text.EndsWith(@"\") || txtTargetDirectory.Text.EndsWith(@"/"))
                {
                    txtTargetDirectory.Text = txtTargetDirectory.Text.Substring(0, txtTargetDirectory.Text.Length - 1);
                    continue;
                }

                break;
            }

            string target = string.Empty;
            string content = string.Empty;
            FileInfo newFileInfo = null;

            foreach (ListViewItem item in listView1.Items)
            {
                if (item.Checked == false)
                    continue;

                FileRootDirectory frd = (FileRootDirectory)item.Tag;

                if (frd.Encoding.Equals((Encoding)encodingList2.SelectedItem))
                {
                    continue;
                }

                if (frd.RootDirectory.Length > 0)
                {
                    target = string.Format(@"{0}\{1}", txtTargetDirectory.Text, frd.FileInfo.FullName.Replace(frd.RootDirectory, ""));
                }
                else
                {
                    target = string.Format(@"{0}\{1}", txtTargetDirectory.Text, frd.FileInfo.Name);
                    if (File.Exists(target))
                    {
                        target = string.Format(@"{0}\{1}", txtTargetDirectory.Text, frd.FileInfo.Name.Replace(frd.FileInfo.Extension, ""), Guid.NewGuid().ToString(), frd.FileInfo.Extension);
                    }
                }

                newFileInfo = new FileInfo(target);
                if (!newFileInfo.Directory.Exists)
                {
                    Directory.CreateDirectory(newFileInfo.Directory.FullName);
                }

                if (File.Exists(target))
                {
                    File.Delete(target);
                }

                content = string.Empty;
                using (var fs = File.OpenRead(frd.FileInfo.FullName))
                {
                    fs.Position = 0;
                    StreamReader sr = new StreamReader(fs, frd.Encoding);
                    content = sr.ReadToEnd();
                    sr.Close();
                    //while (sr.Peek() > 0)
                    //{
                    //    sw.WriteLine(sr.ReadLine());
                    //}
                }

                using (var newFs = File.Open(target, FileMode.CreateNew, FileAccess.Write))
                {
                    newFs.Position = 0;
                    StreamWriter sw = new StreamWriter(newFs, (Encoding)encodingList2.SelectedItem);
                    sw.Write(content);
                    sw.Flush();
                    sw.Close();
                }

            }



        }

        byte[] unicode = new byte[] { Convert.ToByte("FF", 16), Convert.ToByte("FE", 16) };
        byte[] bgEndianUnicode = new byte[] { Convert.ToByte("FE", 16), Convert.ToByte("FF", 16) };
        byte[] utf8 = new byte[] { Convert.ToByte("EF", 16), Convert.ToByte("BB", 16), Convert.ToByte("BF", 16) };

        private Encoding CheckEncoding(FileInfo fi)
        {
            byte[] bs = new byte[3];
            int index = 0;
            using (var fs = System.IO.File.OpenRead(fi.FullName))
            {
                while (index < bs.Length && fs.CanRead)
                {
                    fs.Read(bs, index++, 1);
                }
            }

            if (CompareBytes(bs, utf8))
            {
                return System.Text.Encoding.UTF8;
            }
            else if (CompareBytes(bs, unicode))
            {
                return System.Text.Encoding.Unicode;
            }
            else if (CompareBytes(bs, bgEndianUnicode))
            {
                return System.Text.Encoding.BigEndianUnicode;
            }
            else
            {
                if (encodingList1.Text == "default")
                {
                    return System.Text.Encoding.Default;
                }
                else
                {
                    try
                    {
                        Encoding enc = System.Text.Encoding.GetEncoding(encodingList1.Text);
                        return enc;
                    }
                    catch (Exception)
                    {
                        return System.Text.Encoding.Default;
                    }
                }
            }

        }

        private bool CompareBytes(byte[] bt1, byte[] bt2)
        {
            bool res = true;
            int len = Math.Min(bt1.Length, bt2.Length);
            for (int i = 0; i < len; i++)
            {
                res = res && bt1[i].Equals(bt2[i]);
            }
            //bool res= bt1[0].Equals(bt2[0]) && bt1[1].Equals(bt2[1]);            
            return res;
        }


        class FileRootDirectory
        {
            public FileInfo FileInfo { get; set; }
            public string RootDirectory { get; set; }
            public Encoding Encoding { get; set; }
        }

        private void EncodeConvert_Resize(object sender, EventArgs e)
        {
            listView1.Columns[0].Width = Convert.ToInt32(listView1.Width * 0.2);
            listView1.Columns[1].Width = Convert.ToInt32(listView1.Width * 0.6);
            listView1.Columns[2].Width = Convert.ToInt32(listView1.Width * 0.16);
        }

    }
}
